package com.hup.minicontroller.common.framework;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

/**
 * 子线程Handler;<pre>
 * (写本类时不知道有)安卓自带的
 * mHandlerThread = new HandlerThread("LFEncode");
 * mHandlerThread.start();
 * mEncoderHandler = new Handler(mHandlerThread.getLooper());
 */
public class SubThreadHandler extends Handler {
    private static final String TAG = SubThreadHandler.class.getSimpleName();

    private final Looper looper;

    public SubThreadHandler(String threadName) {
        this(threadName, null);
    }

    /**
     * @param exitCallback 线程退出时的回调,用于如unregister
     */
    public SubThreadHandler(String threadName, Runnable exitCallback) {
        super(SubThread.createAndStart(threadName, exitCallback).looper);
        looper = getLooper();
    }

    /**
     * @param quitSafely true-等待之前的消息处理完后再退出,false-马上退出,不处理剩余的消息
     */
    public void doTerminate(boolean quitSafely) {
        if (quitSafely) {
            looper.quitSafely();
        } else {
            looper.quit();
        }
    }

    /**
     * 创建子线程Handler,并且注册到 {@link BaseApplication},子线程结束时自动注销
     */
    public static SubThreadHandler registerSubThreadHandler(String threadName) {
        SubThreadHandler subThreadHandler = new SubThreadHandler(threadName, () -> BaseApplication.removeBean(SubThreadHandler.class));
        BaseApplication.putBean(subThreadHandler);
        return subThreadHandler;
    }

    /**
     * {@link android.os.HandlerThread}
     */
    private static class SubThread extends Thread {
        private final Runnable exitCallback;
        private Looper looper;

        public static SubThread createAndStart(String threadName, Runnable exitCallback) {
            SubThread subThread = new SubThread(threadName, exitCallback);
            subThread.start();
            subThread.waitUntilGetLooper();
            return subThread;
        }

        public SubThread(String threadName, Runnable exitCallback) {
            super(threadName);
            this.exitCallback = exitCallback;
        }

        @Override
        public void run() {
            Log.i(TAG, "run: " + getName() + "子线程已启动");
            Looper.prepare();//创建当前线程的Looper
            looper = Looper.myLooper();//获取刚刚创建的Looper实例
            Log.i(TAG, "run: 已取得looper,notifyAll");
            synchronized (this) {
                notifyAll();
            }
            Looper.loop();//开始阻塞线程,轮询消息队列
            Log.i(TAG, "run: " + getName() + "子线程结束");
            if (exitCallback != null) exitCallback.run();
        }

        public void waitUntilGetLooper() {
            try {
                while (looper == null) {
                    Log.i(TAG, "waitUntilGetLooper: 开始等待");
                    synchronized (this) {
                        wait();
                    }
                    Log.i(TAG, "waitUntilGetLooper: 等待被唤醒");
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                Log.i(TAG, "waitUntilGetLooper: " + e);
            }
        }

    }

}
